﻿using System.Dynamic;
using Basic.FormCollect;
using Basic.FormCollect.Model;
using Basic.FormExtendService;
using Basic.FormModel;
using Basic.FormModel.Form;
using Basic.FormRemoteModel;
using Basic.FormRemoteModel.QueryForm.Model;
using Basic.UserFormService.Interface;
using Basic.UserFormService.PhysicsTable.Model;
using SqlSugar;
using WeDonekRpc.Client;
using WeDonekRpc.Helper;
using WeDonekRpc.Model;
namespace Basic.UserFormService.PhysicsTable
{
    internal class PhysicsQueryService : IPhysicsQueryService
    {

        private readonly ICustomFormCollect _Form;

        private readonly IAgentFormCollect _AgentForm;

        private readonly IPhysicsQueryBodyCollect _QueryTable;

        private readonly IPhysicsQueryFillService _FillService;

        private readonly IFilterQueryService _FilterQuery;

        public PhysicsQueryService ( IAgentFormCollect agentForm,
            IPhysicsQueryBodyCollect queryTable,
            IPhysicsQueryFillService fillRow,
            IUnitDeptService dept,
            ICustomFormCollect form,
            IDictItemService dictItem,
            IEmpService emp,
            IFilterQueryService filter )
        {
            this._FillService = fillRow;
            this._Form = form;
            this._AgentForm = agentForm;
            this._QueryTable = queryTable;
            this._FilterQuery = filter;
        }
        public QueryFormRecord Get ( long formId, long id )
        {
            FormBaseDto form = this._Form.Get<FormBaseDto>(formId);
            if ( form.FormType != FormType.物理表单 )
            {
                throw new ErrorException("form.type.error");
            }
            PhysicsFormBody body = this._QueryTable.Get(formId);
            ExpandoObject row = this._AgentForm.Get(body.Main.TableName, id, body.Main.ColName);
            QueryTableRecord main = new QueryTableRecord
            {
                Id = body.Main.Id,
                Show = body.Main.Show,
                Column = body.Main.GetColumn(false, true),
                Row = this._FillService.Load(row, body.Main.ExtendCol)
            };
            QueryTableRecord[] records = null;
            if ( !body.Children.IsNull() )
            {
                long mainId = Convert.ToInt64(main.Row[ConstDic.KeyColName]);
                records = body.Children.ConvertAll(a =>
               {
                   QueryTableRecord t = new QueryTableRecord
                   {
                       Id = a.Id,
                       Show = a.Show,
                       Column = a.GetColumn(false, true)
                   };
                   ExpandoObject[] rows = this._AgentForm.GetAll(a.TableName, mainId, a.ColName);
                   t.Rows = this._FillService.Load(rows, a.ExtendCol);
                   return t;
               });
            }
            QueryFormRecord record = new QueryFormRecord
            {
                FormName = form.FormName,
                Main = main,
                Children = records
            };
            PhysicsExtendVal vals = this._FillService.GetExtendVal();
            if ( vals == null )
            {
                return record;
            }
            this._FillRow(record.Main, body.Main, vals);
            record.Children?.ForEach(c =>
                {
                    this._FillRows(c, body.Children.Find(a => a.Id == c.Id), vals);
                });
            return record;
        }
        private void _FillRows ( QueryTableRecord record, PhysicsQueryTable table, PhysicsExtendVal vals )
        {
            if ( !table.ExtendCol.IsNull() )
            {
                record.Rows.ForEach(a =>
                {
                    table.ExtendCol.ForEach(c =>
                    {
                        this._FillService.SetValue(c, a, vals);
                    });
                });
            }
        }
        private void _FillRow ( QueryTableRecord record, PhysicsQueryTable table, PhysicsExtendVal vals )
        {
            if ( !table.ExtendCol.IsNull() )
            {
                table.ExtendCol.ForEach(c =>
                {
                    this._FillService.SetValue(c, record.Row, vals);
                });
            }
        }

        public PagingResult<object> Query ( QueryTableParam query, IBasicPage paging )
        {
            PhysicsFormBody body = this._QueryTable.Get(query.FormId);
            List<IConditionalModel> where = this._FilterQuery.ToWhere(body, query.CompanyId, query.QueryParam);
            if ( this._FilterQuery.IsNull )
            {
                return new PagingResult<object>();
            }
            ExpandoObject[] data = this._AgentForm.Query(body.Main.TableName, where, body.Main.ColName, paging, out int count);
            if ( data.IsNull() )
            {
                return new PagingResult<object>();
            }
            if ( !body.Main.ExtendCol.IsNull() )
            {
                this._FillService.InitRows(data, body.Main.ExtendCol);
            }
            return new PagingResult<object>(data, count);
        }
    }
}
